// Datastore.cpp : Implementation of CDatastore

#include "stdafx.h"
#include "Datastore.h"
#include "SqlQueryBuilder.h"
#include "datastoreitems.h"
#include "datastoreitem.h"
#include "Node.h"
#include "FieldDefinition.h"
#include "FieldDefinitions.h"

// CDatastore

STDMETHODIMP CDatastore::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IDatastore
	};

	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CDatastore::Execute(IDatastoreItems** ppDatastoreItems)
{
	_bstr_t sqlText;
	_bstr_t sql;
	BSTR xml;
	TsDatastoreItemTypeEnum itemType;
	m_pQuery->get_SelectionCriteria(&xml);
	m_pQuery->get_DatastoreItemType(&itemType);

	if(!CSqlQueryBuilder::GetInstance().GetSqlString(itemType, xml, sqlText))
    {
		Error(L"Incorrect sql syntax!");
		return E_FAIL;        
    }
    
    ADODB::_RecordsetPtr spRS;
    m_pDBHelper->ExecuteText(sql, spRS);

    CComObject<CDatastoreItems> * pItems = GetComObject<CDatastoreItems>();
	
	while(!spRS->adoEOF)
	{
		int id = spRS->Fields->Item[L"id"]->Value.intVal;
		pItems->AddItem(id);
		spRS->MoveNext();
	}
    
    *ppDatastoreItems = pItems;

 
    return S_OK;
}
STDMETHODIMP CDatastore::get_ProductName(BSTR* pVal)
{
	*pVal = m_pDBHelper->GetProductName();
    return S_OK;
}

STDMETHODIMP CDatastore::get_Query(IQuery** pVal)
{
    *pVal = m_pQuery;
    return S_OK;
}

STDMETHODIMP CDatastore::put_Query(IQuery* newVal)
{
    m_pQuery = newVal;
    return S_OK;
}

STDMETHODIMP CDatastore::GetDatastoreItem(TsDatastoreItemTypeEnum DatastoreItemType, INT Id, IDatastoreItem** ppDatastoreItem)
{
	CComObject<CDatastoreItem> * pDsItem = GetComObject<CDatastoreItem>();
	pDsItem->Init(this, DatastoreItemType, Id);	
	*ppDatastoreItem = pDsItem;
    return S_OK;
}

STDMETHODIMP CDatastore::AddDatastoreItem(TsDatastoreItemTypeEnum DatastoreItemType, IDatastoreItem** NewItem)
{
	CComObject<CDatastoreItem> * pDsItem = GetComObject<CDatastoreItem>();
	pDsItem->Init(this, DatastoreItemType, 0);	
	*NewItem = pDsItem;
	return S_OK;
}


STDMETHODIMP CDatastore::get_RootNode(INode** pVal)
{
	CComObject<CNode> * pNode = GetComObject<CNode>();
	
	ADODB::_RecordsetPtr spRS;
	
	m_pDBHelper->ExecuteText(L"SELECT TOP 1 * FROM Node WHERE Id=0", spRS);
	
	int id = spRS->Fields->Item[L"Id"]->Value.intVal;
	pNode->Init(this, 0);
	return S_OK;
}


STDMETHODIMP CDatastore::get_FieldDefinitions(IFieldDefinitions** pVal)
{
	ADODB::_CommandPtr spCmd;
	m_pDBHelper->GetCommand(spCmd);
	spCmd->CommandText = L"usp_GetFieldDefinitions";
	spCmd->CommandType = ADODB::adCmdStoredProc;
	ADODB::_RecordsetPtr spRS = spCmd->Execute(NULL, NULL, 0);

	CComObject<CFieldDefinitions> * pFieldDefs = GetComObject<CFieldDefinitions>();
	
	while(!spRS->adoEOF)
	{
		CComObject<CFieldDefinition> * pFieldDef = GetComObject<CFieldDefinition>();
		INT id;
		_bstr_t name;
		
		VARIANT_BOOL isEditable;
		VARIANT_BOOL isQueryable;
		VARIANT_BOOL canReadWithoutOpen;
		VARIANT_BOOL isRequired;
		TsFieldEditTypeEnum editType;
		TsDatastoreItemTypeEnum itemType;

		id = spRS->Fields->Item[L"Id"]->Value.intVal;
		name = spRS->Fields->Item[L"FieldName"]->Value.bstrVal;
		isEditable = spRS->Fields->Item[L"IsEditable"]->Value.boolVal;
		//editType = spRS->Fields->Item[L"Id"]->Value.intVal;
	//pFieldDef->m_id=
		isQueryable = spRS->Fields->Item[L"IsQueryable"]->Value.boolVal;
		canReadWithoutOpen = spRS->Fields->Item[L"CanReadWithoutOpen"]->Value.boolVal;
		isRequired = spRS->Fields->Item[L"IsRequired"]->Value.boolVal;

		_bstr_t strEditType = spRS->Fields->Item[L"EditType"]->Value.bstrVal;
		_bstr_t strItemType = spRS->Fields->Item[L"ItemType"]->Value.bstrVal;
		if (strItemType==_bstr_t(L"TEST_CASE"))
		{
			itemType = tsDatastoreItemTypeTestcase;
		}
		else if (strItemType==_bstr_t(L"RESULT"))
		{
			itemType = tsDatastoreItemTypeResult;
		}
		else
		{
			Error(L"Internal error: invalid datastore item type!");
			return E_FAIL;
		}
		if (strEditType == _bstr_t(L"SIMPLE_EDIT"))
		{
			editType = tsFieldEditTypeSimpleEdit;
		}
		else if (strEditType == _bstr_t(L"BASIC_LIST"))
		{
			editType = tsFieldEditTypeBasicList;
		}
		else if (strEditType == _bstr_t(L"DYNAMIC_LIST"))
		{
			editType = tsFieldEditTypeDynamicList;
		}
		else
		{
			Error(L"Internal error: invalid edit type!");
			return E_FAIL;
		}

		pFieldDef->m_id = id;
		pFieldDef->m_editType = editType;
		pFieldDef->m_isEditable = isEditable;
		pFieldDef->m_isQueryable = isQueryable;
		pFieldDef->m_isRequired = isRequired;
		pFieldDef->m_itemType = itemType;
		pFieldDef->m_name = name;
		pFieldDefs->Add(pFieldDef);
		spRS->MoveNext();
	}

	*pVal = pFieldDefs;
	return S_OK;
}
